package hn.sigit.model.hnd.cadastre;

import hn.sigit.model.hnd.special.HND_Lock;
import hn.sigit.model.ladm.spatialunit.LA_LegalSpaceBuildingUnit;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import org.hibernate.annotations.Type;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;

@Entity
@org.hibernate.annotations.Proxy(lazy=false)
@Table(name="HND_BuildingUnit", schema="hnd_cadastre")
@Inheritance(strategy=InheritanceType.JOINED)
@PrimaryKeyJoinColumn(name="HND_BuildingUnitID", referencedColumnName="LA_SpatialUnitID")
public class HND_BuildingUnit extends LA_LegalSpaceBuildingUnit implements Serializable {
	private static final long serialVersionUID = 1L;

	private Integer numberOfFloors = 1;
	private BigDecimal builtArea;
	private BigDecimal value;
	private Geometry shape;
	
	private HND_BuildingType buildingType;
	private List<HND_BuildingMaterial> buildingMaterials;
	
	private HND_LandUse primaryLandUse;
	private HND_LandUse secondaryLandUse;
	private List<HND_LandUse> otherLandUses;

	private HND_Lock lock;
	
	
	@Column(name="NumberOfFloors", nullable=false)
	public Integer getNumberOfFloors() {
		return numberOfFloors;
	}
	public void setNumberOfFloors(Integer numberOfFloors) {
		this.numberOfFloors = numberOfFloors;
	}
	
	@Column(name="BuiltArea", nullable=true)
	public BigDecimal getBuiltArea() {
		return builtArea;
	}
	public void setBuiltArea(BigDecimal builtArea) {
		this.builtArea = builtArea;
	}
	
	@Column(name="Value", nullable=true)
	public BigDecimal getValue() {
		return value;
	}
	public void setValue(BigDecimal value) {
		this.value = value;
	}
	
	
	@Column(name="Shape", nullable=false)
	@Type(type = "org.hibernatespatial.GeometryUserType")
	public Geometry getShape() {
		return shape;
	}
	public void setShape(Geometry value) {
		if (this.shape == null || !this.shape.equalsExact(value)) {
			this.shape = value;
			
			if (value != null) {
				Point newRefPoint = value.getCentroid();
				newRefPoint.setSRID(value.getSRID());
				this.setReferencePoint(newRefPoint);
			}
		}
	}
	
	@ManyToOne(targetEntity=HND_BuildingType.class, optional=true, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.LOCK})
	@JoinColumns({ @JoinColumn(name="BuildingTypeID", referencedColumnName="id") })
	@org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)
	public HND_BuildingType getBuildingType() {
		return buildingType;
	}
	public void setBuildingType(HND_BuildingType buildingType) {
		this.buildingType = buildingType;
	}
	
	
	@ManyToMany(targetEntity=HND_BuildingMaterial.class, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
	@JoinTable(name="HND_BuildingUnit__HND_BuildingMaterial", schema="hnd_cadastre", joinColumns={ @JoinColumn(name="HND_BuildingUnit__HND_BuildingMaterialID") })
	@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)
	public List<HND_BuildingMaterial> getBuildingMaterials() {
		return buildingMaterials;
	}
	public void setBuildingMaterials(List<HND_BuildingMaterial> buildingMaterials) {
		this.buildingMaterials = buildingMaterials;
	}
	
	
	@ManyToOne(targetEntity=HND_LandUse.class, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
	@JoinColumns({ @JoinColumn(name="PrimaryLandUseID") })
	@org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)
	public HND_LandUse getPrimaryLandUse() {
		return primaryLandUse;
	}
	public void setPrimaryLandUse(HND_LandUse primaryLandUse) {
		this.primaryLandUse = primaryLandUse;
	}
	
	@ManyToOne(targetEntity=HND_LandUse.class, fetch=FetchType.LAZY)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
	@JoinColumns({ @JoinColumn(name="SecondaryLandUseID") })
	@org.hibernate.annotations.LazyToOne(value=org.hibernate.annotations.LazyToOneOption.NO_PROXY)
	public HND_LandUse getSecondaryLandUse() {
		return secondaryLandUse;
	}
	public void setSecondaryLandUse(HND_LandUse secondaryLandUse) {
		this.secondaryLandUse = secondaryLandUse;
	}

	@ManyToMany(targetEntity=HND_LandUse.class)
	@org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.LOCK})
	@JoinTable(name="HND_BuildingUnit__HND_LandUse", schema="hnd_cadastre", joinColumns={ @JoinColumn(name="HND_BuildingUnit__HND_LandUseID") })
	@org.hibernate.annotations.LazyCollection(org.hibernate.annotations.LazyCollectionOption.TRUE)
	public List<HND_LandUse> getOtherLandUses() {
		return otherLandUses;
	}
	public void setOtherLandUses(List<HND_LandUse> otherLandUses) {
		this.otherLandUses = otherLandUses;
	}

	
	@Embedded
	public HND_Lock getLock() {
		if (lock == null)
			lock = new HND_Lock();
		return lock;
	}
	public void setLock(HND_Lock lock) {
		this.lock = lock;
	}
}
